﻿// Copyright (c) 2010
// by Michael Washington
// http://openlightgroup.net/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.ComponentModel.Composition;
using System.Windows.Controls;
using System.Linq;
using System.Windows;
using Microsoft.VisualBasic;
using SilverlightDebate.SilverlightDebateWS;

namespace SilverlightDebate
{
    public class MainPageViewModel : INotifyPropertyChanged, IPartImportsSatisfiedNotification
    {
        // Specifies that a property, field, or parameter value should be provided by
        // the System.ComponentModel.Composition.Hosting.CompositionContainer.
        [Import]
        public IDeploymentCatalogService CatalogService { get; set; }

        // Specifies that a property, field, or parameter should be populated with all
        // matching exports by the System.ComponentModel.Composition.Hosting.CompositionContainer.
        [ImportMany(AllowRecomposition = true)]
        public Lazy<UserControl>[] MEFModuleList { get; set; }

        private string strSelectedXAP = "";

        public MainPageViewModel()
        {
            // Set the command properties
            LoadXAPCommand = new DelegateCommand(LoadXAP, CanLoadXAP);
            SetMEFPanelCommand = new DelegateCommand(SetMEFPanel, CanSetMEFPanel);

            // The following line prevents Expression Blend
            // from showing an error when in design mode
            if (!DesignerProperties.IsInDesignTool)
            {
                // This loads the Xaps in the drop down
                LoadListOfXaps();

                // This call causes DeploymentCatalogService() to be called
                CompositionInitializer.SatisfyImports(this);
            }
        }

        // Commands

        #region LoadXAPCommand
        public ICommand LoadXAPCommand { get; set; }

        public void LoadXAP(object param)
        {
            // Get the .xap selected
            strSelectedXAP = (string)param;

            // Have MEF load the .xap
            // (will only add if not already added)
            CatalogService.AddXap(strSelectedXAP);

            LoadSelectedModule();
        }

        private bool CanLoadXAP(object param)
        {
            return true;
        }
        #endregion

        #region SetMEFPanelCommand
        public ICommand SetMEFPanelCommand { get; set; }
        public void SetMEFPanel(object param)
        {
            MefPanel = (Panel)param;
        }

        private bool CanSetMEFPanel(object param)
        {
            // Must be a Panel
            return ((param as Panel) != null);
        }
        #endregion

        // Events

        #region LoadListOfXaps
        private void LoadListOfXaps()
        {
            SilverlightXaps.GetXaps((Param, EventArgs) =>
            {
                if (EventArgs.Error == null)
                {
                    // loop thru each item
                    foreach (string Xap in EventArgs.Result)
                    {
                        // Add to the SilverlightXapList collection
                        SilverlightXapList.Add(Xap);
                    }

                    // if we have any Xaps, set the selected item value to the first one
                    if (SilverlightXapList.Count > 0)
                    {
                        SelectedXapInListProperty = 0;
                    }

                    // if we only have one Xap, load it
                    if (SilverlightXapList.Count > 0)
                    {
                        LoadXAP(SilverlightXapList[0]);
                    }
                }
            });
        }
        #endregion

        #region IPartImportsSatisfiedNotification Members
        // This fires when a .xap has been loaded
        // If the .xap has already been loaded this will not fire
        public void OnImportsSatisfied()
        {
            LoadSelectedModule();
        }
        #endregion

        #region LoadSelectedModule
        private void LoadSelectedModule()
        {
            // Ensure that we have a Panel to add the .xap to
            if (MefPanel != null)
            {
                // Create a name for the .xap without the ".xap" part
                string strRevisedSelectedXAPName = strSelectedXAP.Replace(".xap", ".");

                // Determine if the .xap is already loaded
                var SelectedMEFModuleInPanel = (from Module in MefPanel.Children.Cast<FrameworkElement>()
                                                where Module.ToString().Contains(strRevisedSelectedXAPName)
                                                select Module).FirstOrDefault();

                // If the .xap is not loaded
                if (SelectedMEFModuleInPanel == null)
                {
                    // Clear the panel
                    MefPanel.Children.Clear();

                    // Get the selected .xap 
                    var SelectedMEFModule = (from Module in MEFModuleList.ToList()
                                             where Module.Value.ToString().Contains(strRevisedSelectedXAPName)
                                             select Module).FirstOrDefault();

                    // If the .xap is found
                    if (SelectedMEFModule != null)
                    {
                        // Add the .xap to the main page
                        MefPanel.Children.Add(SelectedMEFModule.Value);

                        // Get the DataContext of the module just loaded (the ViewModel)
                        SilverlightDebateViewModel.MainPageViewModel Module = (SilverlightDebateViewModel.MainPageViewModel)SelectedMEFModule.Value.DataContext;

                        // Get the current RIAAuthenticationHeader
                        RIAAuthenticationHeader AH = (RIAAuthenticationHeader)Application.Current.Resources["RIAAuthenticationHeader"];

                        // Convert RIAAuthenticationHeader to a dictionary
                        Dictionary<string, string> AuthDict = new Dictionary<string, string>();
                        AuthDict.Add("Username", AH.Username);
                        AuthDict.Add("UserID", AH.UserID.ToString());
                        AuthDict.Add("Password", AH.Password);
                        AuthDict.Add("PortalID", AH.PortalID.ToString());
                        AuthDict.Add("IPAddress", AH.IPAddress);

                        // Pass the Dictionary to the ViewModel
                        Module.SetRIAAuthenticationHeader(AuthDict);

                        // Set Webservice address on the ViewModel
                        Module.SetBaseAddress(GetBaseAddress());
                    }
                }
            }
        }
        #endregion

        // Properties

        #region MefPanel
        private Panel _MefPanel;
        public Panel MefPanel
        {
            get { return _MefPanel; }
            private set
            {
                if (MefPanel == value)
                {
                    return;
                }

                _MefPanel = value;
                this.NotifyPropertyChanged("MefPanel");
            }
        }
        #endregion

        #region SelectedXapInListProperty
        private int _SelectedXapInListProperty = -1;
        public int SelectedXapInListProperty
        {
            get
            {
                return this._SelectedXapInListProperty;
            }
            set
            {
                this._SelectedXapInListProperty = value;
                this.NotifyPropertyChanged("SelectedXapInListProperty");
            }
        }
        #endregion

        // Collections

        #region SilverlightXapList
        private ObservableCollection<String> _SilverlightXapList = new ObservableCollection<string>();
        public ObservableCollection<String> SilverlightXapList
        {
            get { return _SilverlightXapList; }
            private set
            {
                _SilverlightXapList = value;
                this.NotifyPropertyChanged("SilverlightXapList");
            }
        }
        #endregion

        // Utility

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion

        #region GetBaseAddress
        private static string GetBaseAddress()
        {
            // Get the web address of the .xap that launched this application
            string strBaseWebAddress = App.Current.Host.Source.AbsoluteUri;
            // Find the position of the ClientBin directory
            int PositionOfClientBin =
                App.Current.Host.Source.AbsoluteUri.ToLower().IndexOf(@"/clientbin");
            // Strip off everything after the ClientBin directory
            strBaseWebAddress = Strings.Left(strBaseWebAddress, PositionOfClientBin);
            // Return the base address
            return string.Format(@"{0}/{1}", strBaseWebAddress, "WebService.asmx");
        }
        #endregion
    }
}
